package project.sample.nio;

import project.sample.protocol.http.*;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.ByteBuffer;
import java.nio.channels.Channel;
import java.nio.channels.SelectionKey;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.Callable;

/**
 * @author: WUZH009
 * @date: 2019/8/23 14:18
 **/
public class NioWorkerThread implements Callable<Void> {

    private SelectionKey key;

    public NioWorkerThread(SelectionKey key) {
        this.key = key;
    }

    @Override
    public Void call() throws Exception {
//        ByteBuffer buffer = (ByteBuffer) key.attachment();
        try (SocketChannel channel = (SocketChannel) key.channel()) {
            ByteBuffer buffer = ByteBuffer.allocate(8192);
            int num = channel.read(buffer);
            if (num == -1) {
                key.cancel();
            }
            buffer.flip();
            String first = readLine(buffer);
            String[] arr = first.split(" ");
            if (arr.length != 3) {
                throw new RuntimeException("http protocol parsed error");
            }
            String method = arr[0];
            String path = arr[1];
            String protocol = arr[2];
            List<HttpHeader> headers = new ArrayList<>();
            int contentLength = -1;
            while (true) {
                String line = readLine(buffer);
                if ("".equals(line)) {
                    break;
                }
                String[] kv = line.split(": ");
                if (kv.length == 2) {
                    if ("Content-Length".equalsIgnoreCase(kv[0])) {
                        contentLength = Integer.parseInt(kv[1]);
                    }
                    headers.add(new HttpHeader(kv[0], new String[]{kv[1]}));
                }
            }
            byte[] body = null;
            if (contentLength > -1) {
                body = new byte[contentLength];
                buffer.get(body);
            }
            HttpRequest request = new DefaultHttpRequest(headers, method, "http://localhost", path, protocol, "localhost", body);
            execute();
            response(channel);
        }
        return null;
    }

    private void execute() {
    }

    private String readLine(ByteBuffer buffer) {
        StringBuilder line = new StringBuilder();
        while (true) {
            if (!buffer.hasRemaining()) {
                break;
            }
            byte b = buffer.get();
            if (b == '\n') {
                break;
            }
            if (b == '\r') {
                continue;
            }
            line.append((char) b);
        }
        return line.toString();

    }

    private void response(SocketChannel channel) throws IOException {
        HttpResponse response = new DefaultHttpResponse(new ArrayList<>(Arrays.asList(new HttpHeader("Content-Type", new String[]{"text/html"}), new HttpHeader("Content-Length", new String[]{"2"}))), 200);
        response.body("ok".getBytes());
        ByteBuffer buffer = ByteBuffer.wrap(response.bytes());
        channel.write(buffer);
    }
}
